package de.tuhh.simsearch.controller;

import java.io.InputStream;
import java.math.BigInteger;
import java.util.List;
import java.util.Set;

import javax.ejb.Local;

import de.tuhh.simsearch.constants.Constants.FilterType;
import de.tuhh.simsearch.constants.Constants.SearchTypes;
import de.tuhh.simsearch.dto.CategoryDTO;
import de.tuhh.simsearch.dto.FileDTO;
//import de.tuhh.simsearch.controller.contentmgmt.interfaces.CategoryDTO;
import de.tuhh.simsearch.dto.GroupDTO;
import de.tuhh.simsearch.dto.PasswordDTO;
import de.tuhh.simsearch.dto.PreferenceDTO;
import de.tuhh.simsearch.dto.UserDTO;

/**
 * The RequestHandlerLocal is the local interface for the RequestHandler. It makes the functions of the RequestHandler available for the Client.
 * 
 * @author SimSearch 1
 * @see RequestHandler
 */
@Local
public interface RequestHandlerLocal {

  /**
   * Registers a user to the system.
   * 
   * @param user
   *          The data transfer object of the user
   * @param pwdto
   *          the dto containing old and new password
   * @return 0 for success, 1 for user already exists, 2 for passwords do not match, 3 for another error
   */
  public int register(UserDTO user, PasswordDTO pwdto);

  // Search

  /**
   * Searches within the groups for a string
   * 
   * @param srchStrng
   *          string to search for
   * @return the group DTOs for the resulting groups
   */
  public List<GroupDTO> searchGroups(String srchStrng);

  /**
   * Searches within the preferences for a string
   * 
   * @param srchStrng
   *          string to search for
   * @return the preference DTOs for the resulting preferences
   */
  public List<PreferenceDTO> searchPreferences(String srchStrng);

  /**
   * Searches within the user names for a string
   * 
   * @param srchStrng
   *          string to search for
   * @return the user DTOs for the resulting users
   */
  public List<UserDTO> searchUsers(String srchStrng);

  /**
   * Searches within the content for a given string. Which file attributes (name, category, metadata, content) are
   * searched is determined by a set of search types.
   * 
   * @param srchStrng
   *          the string to search for
   * @param filter
   *          the filter to be applied
   * @param principal
   *          the current logged in user
   * @param searchTypes
   *          which file attributes should be searched
   * @return the list of resulting files
   */
  public List<FileDTO> searchContent(String srchStrng, FilterType filter, String principal, Set<SearchTypes> searchTypes);

  /**
   * Searches for categories that match or contain a given string
   * 
   * @param searchString
   *          the string to search for
   * @return the list of category DTOs found by the search
   */
  public List<CategoryDTO> searchCategories(String searchString);

  // Getters

  /**
   * Returns the DTO for the user with given name
   * 
   * @param usrName
   *          the name of the user
   * @return the DTO for the user
   */
  public UserDTO getUser(String usrName);

  /**
   * Returns the DTO for a group with given name
   * 
   * @param grpName
   *          the name of the group the search for
   * @return the DTO for the group with this name
   */
  public GroupDTO getGroup(String grpName);

  /**
   * Returns the preference DTO for a certain preference type. A preference has a name and a content type.
   * 
   * @param prefName
   *          the name of the preference
   * @param contentType
   *          the content type for the preference
   * @return the DTO of the preference
   */
  public PreferenceDTO getPreference(String prefName, String contentType);

  /**
   * Lists the joined groups of the user. The list does not contain groups where membership is pending
   * 
   * @param usrName
   *          the name of the user
   * @return the list of the joined groups as DTOs of the user
   */
  public List<GroupDTO> getJoinedGroups(String usrName);

  /**
   * Lists the preferences of a certain user
   * 
   * @param usrName
   *          the name of the user
   * @return the list of preferences as DTOs of the user
   */
  public List<PreferenceDTO> getPreferences(String usrName);

  /**
   * The requested groups for a certain user
   * 
   * @param usrName
   *          the name of the user
   * @return the list of requested groups as DTOs of the user
   */
  public List<GroupDTO> getRequestedGroups(String usrName);

  /**
   * Lists the members of a group in a DTO (not containing pending members)
   * 
   * @param grpName
   *          the name of the group
   * @return the list of group members as DTOs
   */
  public List<UserDTO> getGroupMembers(String grpName);

  /**
   * Get the FileDTO of a file by submitting its id.
   * 
   * @param id
   *          the id of the file
   * @return the file DTO
   */
  public FileDTO getFileInfo(BigInteger id);

  // "Setters"

  /**
   * Adds a preference to current user.
   * 
   * @param principal
   *          The current logged in user
   * @param prefToAdd
   *          the preference to add to the user's profile
   * @return true if operation was successful, otherwise false
   */
  public boolean addPreferenceToUser(String principal, PreferenceDTO prefToAdd);

  /**
   * Accepts user to a group. Only group owner can accept groups
   * 
   * @param principal
   *          The currently logged in user
   * @param grpName
   *          the name of the group
   * @param usrName
   *          the name of the user which should be accepted
   * @return true if operation was successful, otherwise false
   */
  public boolean acceptUserToGroup(String principal, String grpName, String usrName);

  /**
   * Adds a user to the pending users of a group. The group admin can then decide whether the user should be a full
   * member of the group
   * 
   * @param principal
   *          the current logged in user
   * @param grpName
   *          the name of the group
   * @return true if operation was successful, otherwise false
   */
  public boolean addUserAsPendingToGroup(String principal, String grpName);

  /**
   * Adds a new group to the database, sets the current logged in user as owner
   * 
   * @param principal
   *          The current logged in user, the owner of the new group
   * @param grp
   *          the group that should be generated
   * @return true if operation was successful, otherwise false
   */
  public boolean generateGroup(String principal, GroupDTO grp);

  // Update

  /**
   * Changes the password of current logged in user
   * 
   * @param principal
   *          the current logged in user
   * @param user
   *          the user to change the password for
   * @param pwDto
   *          the old and new passwords of the user
   * @return true if operation was successful, otherwise false
   */
  public boolean updatePassword(String principal, UserDTO user, PasswordDTO pwDto);

  // Delete

  /**
   * Deletes a user from the system. Only possbile for the user him- or herself. Could be extended, so that admin can
   * also delete user
   * 
   * @param principal
   *          the current logged in user
   * @param usr
   *          the name of the user to delete
   * @return true if operation was successful, otherwise false
   */
  public boolean deleteUser(String principal, String usr);

  /**
   * Deletes a group. Only possible for group administrator
   * 
   * @param principal
   *          the user name of the current logged in user
   * @param grp
   *          the name of the group to delete
   * @return true if operation was successful, otherwise false
   */
  public boolean deleteGroup(String principal, String grp);

  /**
   * Deletes a preference from the user profile of current logged in user
   * 
   * @param principal
   *          the user name of the current logged in user
   * @param pdto
   *          the dto of the preference to delete
   * @return true if operation was successful, otherwise false
   */
  public boolean deletePreference(String principal, PreferenceDTO pdto);

  /**
   * Uploads a file to the server.
   * 
   * @param dto
   *          the DTO containing the file name, content type, description and categories
   * @param is
   *          the input stream for the file
   * @return the file DTO containing the generated id for the file
   */
  public FileDTO uploadFile(FileDTO dto, InputStream is);

  /**
   * Download a file from the server by submitting a DTO
   * 
   * @param dto
   *          the DTO for the file to download
   * @return the InputStream to download the file
   */
  public InputStream downloadFile(FileDTO dto);

  /**
   * Download a file from the server with given id
   * 
   * @param id
   *          the file id
   * @return the InputStream to download the file
   */
  public InputStream downloadFile(BigInteger id);

  /**
   * Check if user with name 'name' is in group 'gname'.
   * 
   * @param name
   *          name of the user to check
   * @param gName
   *          name of the group to check
   * @return true if user is in group, else false
   */
  public boolean isUserInGroup(String name, String gName);

  /**
   * Removes a user from group. Can be done by group administrator or the user him/herself.
   * 
   * @param principal the current logged in user
   * @param userToDelete the user to delete
   * @param gName the name of the group
   * @return true if operation was successful
   */
  public boolean removeUserFromGroup(String principal, String userToDelete, String gName);

  /**
   * Only possible for (content) admin. Generates a new category (and preference).
   * 
   * @param principal
   *          the current logged in user
   * @param dto
   *          the category
   * @return true if success, else false
   */
  public boolean generateCategory(String principal, CategoryDTO dto);

  /**
   * Checks whether a user is admin of given group
   * 
   * @param name
   *          the name of the user to check
   * @param gName
   *          the name of the group
   * @return true if user is admin
   */
  public boolean isUserGroupAdmin(String name, String gName);

  /**
   * Checks whether a user is content admin
   * 
   * @param name
   *          the name of the user to check
   * @return true if user is content admin
   */
  public boolean isUserContentAdmin(String name);

}
